home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / FPSE_src / cpu / ix86 / compile.c < prev   
Encoding:
C/C++ Source or Header  |  2000-01-01  |  35.5 KB  |  1,400 lines

  1. #include "fpse.h"
  2.  
  3. #undef PRINTF
  4. #undef rs
  5. #undef rt
  6. #undef rd
  7.  
  8. #define PRINTF  if (1==0) printf
  9. #define   rs   rsno*4
  10. #define   rt   rtno*4
  11. #define   rd   rdno*4
  12.  
  13. #define   idxCPR0   35*4
  14. #define   idxCCR0   (35+32)*4
  15. #define   idxCPR2   (35+64)*4
  16. #define   idxCCR2   (35+96)*4
  17. #define   rPC  32*4
  18. #define   idxrLO    33*4
  19. #define   idxrHI    34*4
  20.  
  21. #define   PP   0    /* Pentium optimize */
  22.  
  23. #define COMPILERSIZE    (1024*1024)
  24.  
  25. typedef void (*funcptr)();
  26.  
  27. /* runtime function */
  28.  
  29. int breakpoint = 0; /* 0x1a1c; */
  30. int writebreak = 0; /*xa000e28c;*/
  31. /*
  32. void watch(void)
  33. {
  34. static char *regname[32] = {
  35.      "zero","at","v0","v1","a0","a1","a2","a3",
  36.      "t0","t1","t2","t3","t4","t5","t6","t7",
  37.      "s0","s1","s2","s3","s4","s5","s6","s7",
  38.      "t8","t9","k0","k1","gp","sp","fp","ra"
  39. };
  40.  
  41.      int i;
  42.      for(i=0;i<32;i++) 
  43.           printf("%-4s = %08x ",regname[i],(int)reg.r[i]);
  44.      printf("\n");
  45. }
  46. */
  47. static void swl(UINT32 adr,UINT32 r)
  48. {
  49.           UINT32    data = read32(adr&~3);
  50.           switch(adr&3) {
  51. #if TARGET_BIG_ENDIAN
  52.           case 0: data = r; break;
  53.           case 1: data = (data & 0xff000000) | (r>> 8); break;
  54.           case 2: data = (data & 0xffff0000) | (r>>16); break;
  55.           case 3: data = (data & 0xffffff00) | (r>>24); break;
  56. #else
  57.           case 3: data = r; break;
  58.           case 2: data = (data & 0xff000000) | (r>> 8); break;
  59.           case 1: data = (data & 0xffff0000) | (r>>16); break;
  60.           case 0: data = (data & 0xffffff00) | (r>>24); break;
  61. #endif
  62.           }
  63.           write32(adr&~3,data);
  64. }
  65.  
  66. static void swr(UINT32 adr,UINT32 r)
  67. {
  68.           UINT32    data = read32(adr&~3);
  69.           switch(adr&3) {
  70. #if TARGET_BIG_ENDIAN
  71.           case 0: data = (data & 0x00ffffff) | (r<<24); break;
  72.           case 1: data = (data & 0x0000ffff) | (r<<16); break;
  73.           case 2: data = (data & 0x000000ff) | (r<< 8); break;
  74.           case 3: data = r; break;
  75. #else
  76.           case 3: data = (data & 0x00ffffff) | (r<<24); break;
  77.           case 2: data = (data & 0x0000ffff) | (r<<16); break;
  78.           case 1: data = (data & 0x000000ff) | (r<< 8); break;
  79.           case 0: data = r; break;
  80. #endif
  81.           }
  82.           write32(adr&~3,data);
  83. }
  84.  
  85. static UINT32 lwl(UINT32 adr,UINT32 r)
  86. {
  87.           UINT32    data = read32(adr&~3);
  88.           switch(adr&3) {
  89. #if TARGET_BIG_ENDIAN
  90.           case 0: r = data; break;
  91.           case 1: r = (r & 0x000000ff) | (data<< 8); break;
  92.           case 2: r = (r & 0x0000ffff) | (data<<16); break;
  93.           case 3: r = (r & 0x00ffffff) | (data<<24); break;
  94. #else
  95.           case 3: r = data; break;
  96.           case 2: r = (r & 0x000000ff) | (data<< 8); break;
  97.           case 1: r = (r & 0x0000ffff) | (data<<16); break;
  98.           case 0: r = (r & 0x00ffffff) | (data<<24); break;
  99. #endif
  100.           }
  101.           return r;
  102. }
  103.  
  104. static UINT32 lwr(UINT32 adr,UINT32 r)
  105. {
  106.           UINT32    data = read32(adr&~3);
  107.           switch(adr&3) {
  108. #if TARGET_BIG_ENDIAN
  109.           case 0: r = (r & 0xffffff00) | (data>>24); break;
  110.           case 1: r = (r & 0xffff0000) | (data>>16); break;
  111.           case 2: r = (r & 0xff000000) | (data>> 8); break;
  112.           case 3: r = data; break;
  113. #else
  114.           case 3: r = (r & 0xffffff00) | (data>>24); break;
  115.           case 2: r = (r & 0xffff0000) | (data>>16); break;
  116.           case 1: r = (r & 0xff000000) | (data>> 8); break;
  117.           case 0: r = data; break;
  118. #endif
  119.           }
  120.           return r;
  121. }
  122.  
  123. #define   NOT_IMPREMENT(cd)   printf("not imprement %s: %08x\n",cd,(int)code);
  124.  
  125. static int lastax = -1;
  126.  
  127. #define MAXMEMBLKS      1024
  128.  
  129. static UINT32  MemBlocksIdx=0;
  130. static UINT32  MemBlocks[MAXMEMBLKS*2];
  131. static UINT8  *compilebuf;
  132. static UINT32 *realpc;
  133. static UINT8  *pcptr;
  134. static char    endflg;
  135. static UINT8   exitflg=0;
  136.  
  137. #define   COMPILED(adr)  realpc[( (adr<0xbfc00000) ?                          \
  138.                                 ((adr>=0x1f000000 && adr<0x1f020000) ?       \
  139.                                  (adr-0x1f000000+0x280000):(adr&0x1fffff)) : \
  140.                                  (adr-0xbfc00000+0x200000) )/4]
  141.  
  142. static int SearchFreeSlot()
  143. {
  144.     int x;
  145.  
  146.     for (x=0;x<MAXMEMBLKS;x++)
  147.         if (MemBlocks[x*2] > 0x1FFFFFFF) return x;
  148.  
  149.     x = MemBlocksIdx;
  150.     if (++MemBlocksIdx >= MAXMEMBLKS)
  151.         MemBlocksIdx = 0;
  152.     if (MemBlocks[x*2] < 0x1FFFFFFF)
  153.     {
  154.         memset(&COMPILED(MemBlocks[x*2]),0,
  155.                MemBlocks[x*2+1] - MemBlocks[x*2] );
  156.     }
  157.  
  158.     return x;
  159. }
  160.  
  161. // int dmact = 0;
  162.  
  163. void CompileFlush(UINT32 start, UINT32 end)
  164. {
  165.     UINT32 x,mstart,mend;
  166.  
  167.     if (!compile) return;
  168.  
  169.     start &= 0x1FFFFFFF;
  170.     end   &= 0x1FFFFFFF;
  171. /*
  172.     if (start == 0x1E000)
  173.     {
  174.         printf("Found CDMA - ACT=%08x-%08x\n",start,end);
  175.  
  176.         dmact= 1;
  177.     }
  178. */
  179.     for (x=0; x<MAXMEMBLKS; x++)
  180.     {
  181.         mstart = MemBlocks[x*2];
  182.         mend   = MemBlocks[x*2+1];
  183. /*
  184.         if (dmact) {
  185.             printf("-> %03x) %08x-%08x\n", x, mstart, mend);
  186.             if (x == 0x199)
  187.                 printf("reached limit \n");
  188.         }
  189. */
  190.         if ((start >= mstart && start <= mend) ||
  191.             (mstart >= start && mstart <= end))
  192.         {
  193. //            printf("invalidate blk %08x-%08x\n",mstart,mend);
  194.             MemBlocks[x*2]   = 0xFFFFFFF;
  195.             MemBlocks[x*2+1] = 0xFFFFFFF;
  196.             memset(&COMPILED(mstart),0,mend-mstart);
  197.         }
  198.  
  199.     }
  200. //    dmact = 0;
  201. }
  202.  
  203. UINT32 jmppc(UINT32 Pc)
  204. {
  205.     int pc,startptr,x;
  206.  
  207.     if (update_hw()) {
  208.         if ((SR&0x401)==0x401) {
  209.             EPC = Pc;
  210.             CAUSE = 0x400;
  211.             SR = (SR & ~0x3f)| ((SR<<2)&0x3f);
  212.             Pc = 0x80000080;
  213.         }
  214.     }
  215.     switch(Pc) {
  216.     case 0:
  217. // Oooppsss!! We need also to release everything
  218. // (otherwise DirectDraw will surely kill your PC!)
  219.         printf("PC = 0 at $%08x\n",(int)(PC));
  220.         if (exitflg)
  221.         {
  222.             hw_close();
  223.             memfree();
  224.             exit(-1);
  225.         }
  226.         break;
  227.     case 0xa0:
  228.     case 0xb0:
  229.     case 0xc0:
  230.         PC = Pc;
  231.         biosprint(Pc);
  232.         Pc = PC;
  233.         break;
  234.     case 0x80000080:
  235.         PC = Pc;
  236.         exception_handler();
  237.         Pc = PC;
  238.         break;
  239.     }
  240.  
  241.     if (COMPILED(Pc)) return COMPILED(Pc);
  242.  
  243.     SETPC(Pc);
  244.     endflg = 0;
  245.     pc = Pc;
  246.  
  247.     if (pcptr > compilebuf+COMPILERSIZE-1024) // End-of-buffer is near
  248.     {                                         // Flush all
  249.         memset(MemBlocks,0xFF,MAXMEMBLKS*2*sizeof(UINT32));
  250.         memset(realpc,0,0x200000+0x80000+0x20000);
  251.         pcptr = compilebuf;
  252.     }
  253.     startptr = (int)pcptr;
  254.     x = SearchFreeSlot();
  255.  
  256.     while(!endflg)
  257.         pc = compile1(pc);
  258.  
  259.     MemBlocks[x*2]   = (Pc & 0x1FFFFFFF);
  260.     MemBlocks[x*2+1] = (pc & 0x1FFFFFFF);
  261.  
  262.     PRINTF("compile : psx = %08x-%08x(%08x) pc = %08x-%08x(%08x)\n",
  263.            (int)Pc,(int)pc,(int)(pc-Pc),(int)startptr,(int)pcptr,(int)(pcptr-startptr));
  264.  
  265.     return COMPILED(Pc);
  266. }
  267.  
  268. #if 1
  269.  
  270. #define   GENCODE1(c0)   *pcptr++=c0
  271. #define   GENCODE2(c0,c1)     pcptr[0]=c0;pcptr[1]=c1; pcptr+=2
  272. #define   GENCODE3(c0,c1,c2)  pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2; pcptr+=3
  273. #define   GENCODE4(c0,c1,c2,c3)    pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;pcptr[3]=c3;pcptr+=4
  274. #define   GENCODE1i(c0,imm)   pcptr[0]=c0; *(long*)&pcptr[1]=(long)imm; pcptr+=5
  275. #define   GENCODE2i(c0,c1,imm)     pcptr[0]=c0;pcptr[1]=c1; *(long*)&pcptr[2]=(long)imm; pcptr+=6
  276. #define   GENCODE3i(c0,c1,c2,imm)  pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2; *(long*)&pcptr[3]=(long)imm; pcptr+=7
  277.  
  278. //#define DISASM(code,pc)
  279. #define   DISASM    if (verbose) disasm2
  280. static void disasm2(long code,long addr)
  281. {
  282.      char buf[256];
  283.      disasm(buf,code,addr);
  284.      printf(";%08lx %08lx   %s\n",addr,code,buf);
  285. }
  286.  
  287. #else
  288.  
  289. #define   DISASM    if (verbose) disasm2
  290. static void disasm2(long code,long addr)
  291. {
  292.      char buf[256];
  293.      disasm(buf,code,addr);
  294.      printf(";%08lx %08lx   %s\n",addr,code,buf);
  295. }
  296.  
  297. static void GENCODE1(unsigned char  c0)
  298. {
  299.      PRINTF(" %p %02x                ",pcptr,c0);
  300.      *pcptr++=c0;
  301. }
  302. static void GENCODE2(unsigned char  c0,unsigned char  c1)
  303. {
  304.      PRINTF(" %p %02x %02x             ",pcptr,c0,c1);
  305.      pcptr[0]=c0;pcptr[1]=c1;
  306.      pcptr+=2;
  307. }
  308. static void GENCODE3(unsigned char  c0,unsigned char  c1,unsigned char  c2)
  309. {
  310.      PRINTF(" %p %02x %02x %02x          ",pcptr,c0,c1,c2);
  311.      pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;
  312.      pcptr+=3;
  313. }
  314. static void GENCODE4(unsigned char  c0,unsigned char  c1,unsigned char  c2,unsigned char  c3)
  315. {
  316.      PRINTF(" %p %02x %02x %02x %02x       ",pcptr,c0,c1,c2,c3);
  317.      pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;pcptr[3]=c3;
  318.      pcptr+=4;
  319. }
  320.  
  321. static void GENCODE1i(unsigned char  c0,int imm)
  322. {
  323.      PRINTF(" %p %02x %08x       ",pcptr,c0,imm);
  324.      pcptr[0]=c0;
  325.      *(long*)&pcptr[1] = imm;
  326.      pcptr+=5;
  327. }
  328. static void GENCODE2i(unsigned char  c0,unsigned char  c1,int imm)
  329. {
  330.      PRINTF(" %p %02x %02x %08x    ",pcptr,c0,c1,imm);
  331.      pcptr[0]=c0;pcptr[1]=c1;
  332.      *(long*)&pcptr[2] = imm;
  333.      pcptr+=6;
  334. }
  335. static void GENCODE3i(unsigned char  c0,unsigned char  c1,unsigned char  c2,int imm)
  336. {
  337.      PRINTF(" %p %02x %02x %02x %08x ",pcptr,c0,c1,c2,imm);
  338.      pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;
  339.      *(long*)&pcptr[3] = imm;
  340.      pcptr+=7;
  341. }
  342.  
  343.  
  344. #endif
  345.  
  346. void compile_init(void)
  347. {
  348.     compilebuf = malloc(COMPILERSIZE);
  349.     realpc = malloc(0x200000+0x80000+0x20000);
  350.     memset(realpc,0,0x200000+0x80000+0x20000);
  351.     memset(MemBlocks,0xFF,MAXMEMBLKS*2*sizeof(UINT32));
  352.     pcptr = compilebuf;
  353. }
  354.  
  355. static void load_ax(int r)
  356. {
  357.      if (!r) {
  358.           GENCODE2(0x31,0xc0);
  359.           PRINTF("xor eax,eax\n");
  360.      } else {
  361.           GENCODE3(0x8b,0x46,r);
  362.           PRINTF("mov eax,[esi+%d]\n",r);
  363.      }
  364.      lastax = r;
  365. }
  366.  
  367. #if 0
  368. static void load_dx(int r)
  369. {
  370.      GENCODE3(0x8b,0x56,r);
  371.      PRINTF("mov edx,[esi+%d]\n",r);
  372. }
  373. #endif
  374.  
  375. static void store_ax(int r)
  376. {
  377.      if (!r) return;
  378.      GENCODE3(0x89,0x46,r);
  379.      PRINTF("mov [esi+%d],eax\n",r);
  380.      //isimm[r/4] = 0;
  381.      lastax = r;
  382. }
  383.  
  384. static void store_imm(int r,int imm)
  385. {
  386.      GENCODE3i(0xc7,0x46,r,imm);
  387.      PRINTF("mov dword [esi+%d],0%xh\n",r,imm);
  388.      //isimm[r/4] = imm;
  389.      lastax = -1;
  390. }
  391.  
  392. static void push_imm(int imm)
  393. {
  394.      GENCODE1i(0x68,imm);
  395.      PRINTF("push 0%xh\n",imm);
  396. }
  397.  
  398. static void push_ax(void)
  399. {
  400.      GENCODE1(0x50);
  401.      PRINTF("push eax\n");
  402. }
  403.  
  404. static void push_r(int r)
  405. {
  406.      if (!r) {
  407.           load_ax(r);
  408.           push_ax();
  409.      } else {
  410. #if PP
  411.           load_ax(r);
  412.           push_ax();
  413. #else
  414.           GENCODE3(0xff,0x76,r);
  415.           PRINTF("push dword [esi+%d]\n",r);
  416. #endif
  417.      }
  418. }
  419.  
  420. /* ofset > 127 */
  421. static void load2_ax(int r)
  422. {
  423.      GENCODE2i(0x8b,0x86,r);
  424.      PRINTF("mov eax,[esi+%d]\n",r);
  425. }
  426.  
  427. static void store2_ax(int r)
  428. {
  429.      GENCODE2i(0x89,0x86,r);
  430.      PRINTF("mov [esi+%d],eax\n",r);
  431. }
  432.  
  433. static void store2_dx(int r)
  434. {
  435.      GENCODE2i(0x89,0x96,r);
  436.      PRINTF("mov [esi+%d],edx\n",r);
  437. }
  438.  
  439. static void push2_r(int r)
  440. {
  441.      GENCODE2i(0xff,0xb6,r);
  442.      PRINTF("push dword [esi+%d]\n",r);
  443. }
  444.  
  445.  
  446. static void alu_i(UINT32 code,char *str,int op_r,int op_m)
  447. {
  448.      int imm = immU;
  449. /*
  450.      05 ii ii ii ii add  eax,imm
  451.      81 46 xx ii ii ii ii add dword [esi+rt],imm
  452.      25 ii ii ii ii and  eax,imm
  453.      81 66 xx ii ii ii ii and dword [esi+rt],imm
  454.      0d ii ii ii ii or   eax,imm
  455.      81 4e xx ii ii ii ii or  dword [esi+rt],imm
  456.      35 ii ii ii ii xor  eax,imm
  457.      81 76 xx ii ii ii ii xor dword [esi+rt],imm
  458.      3d ii ii ii ii cmp  eax,imm
  459.      81 7e xx ii ii ii ii cmp dword [esi+rt],imm
  460.      b8 ii ii ii ii mov  eax,imm
  461.      c7 46 xx ii ii ii ii mov dword [esi+rt],imm
  462. */
  463.  
  464.      /* 8b 46 xx mov eax,[esi+xx] */
  465.      /* 89 46 xx mov [esi+xx],eax */
  466.  
  467.      if (!rt) return;
  468.  
  469.      if (rs) {
  470.           if (rs==rt) {
  471.                GENCODE3i(0x81,op_m,rs,imm);
  472.                PRINTF("%s dword [esi+%d],0%xh\n",str,(int)rs,imm);
  473.                /*if (rt==lastax)*/ lastax=-1;
  474.           } else {
  475.                load_ax(rs);
  476.                GENCODE1i(op_r,imm);
  477.                PRINTF("%s eax,%d\n",str,imm);
  478.                store_ax(rt);
  479.           }
  480.      } else {
  481.           store_imm(rt,imm);
  482.      }
  483. }
  484.  
  485. static void add_imm(int imm)
  486. {
  487.      if (!imm) return;
  488.  
  489.      if (imm<-128 || imm>127) {
  490.           GENCODE1i(0x05,imm);
  491.           PRINTF("add eax,0%xh\n",imm);
  492.      } else if (imm==1) {
  493.           GENCODE1(0x40);
  494.           PRINTF("inc eax\n");
  495.      } else if (imm==-1) {
  496.           GENCODE1(0x48);
  497.           PRINTF("dec eax\n");
  498.      } else {
  499.           GENCODE3(0x8d,0x40,imm);
  500.           PRINTF("lea eax,[eax+%d]\n",imm);
  501.      }
  502. }
  503.  
  504. static void add_i(UINT32 code)
  505. {
  506. /*
  507.      05 ii ii ii ii add  eax,imm
  508.      81 46 xx ii ii ii ii add dword [esi+rt],imm
  509. */
  510.      int imm = immS;
  511.  
  512.      if (!rt) return;
  513.  
  514.      if (rs) {
  515.           if (rs==rt) {
  516.                if (imm==1) {
  517.                     GENCODE3(0xff,0x46,rs);
  518.                     PRINTF("inc [esi+%d]\n",(int)rs);
  519.                } else if (imm==-1) {
  520.                     GENCODE3(0xff,0x4e,rs);
  521.                     PRINTF("dec [esi+%d]\n",(int)rs);
  522.                } else if (imm) {
  523.                     GENCODE3i(0x81,0x46,rs,imm);
  524.                     PRINTF("add dword [esi+%d],0%xh\n",(int)rs,imm);
  525.                }
  526.           } else {
  527.                load_ax(rs);
  528.                add_imm(imm);
  529.                store_ax(rt);
  530.           }
  531.      } else {
  532.           store_imm(rt,imm);
  533.      }
  534. }
  535.  
  536. static void alu_r(UINT32 code,char *str,int op_1,int op_2)
  537. {
  538. /*
  539.      03 46 xx add   eax,[esi+rt]
  540.      01 46 xx add   [esi+rt],eax
  541.      2b 46 xx sub   eax,[esi+rt]
  542.      29 46 xx sub   [esi+rt],eax
  543.      23 46 xx and   eax,[esi+rt]
  544.      21 46 xx and   [esi+rt],eax
  545.      0b 46 xx or    eax,[esi+rt]
  546.      09 46 xx or    [esi+rt],eax
  547.      33 46 xx xor   eax,[esi+rt]
  548.      31 46 xx xor   [esi+rt],eax
  549.      3b 46 xx cmp   eax,[esi+rt]
  550.      39 46 xx cmp   [esi+rt],eax
  551. */
  552.      if (!rd) return;
  553.  
  554.      if (rs) {
  555. #if !PP
  556.           if (rs==rd) {
  557.                load_ax(rt);
  558.                GENCODE3(op_2,0x46,rd);
  559.                PRINTF("%s [esi+%d],eax\n",str,(int)rd);
  560.                //isimm[rdno] = 0;
  561.                return;
  562.           } else
  563. #endif
  564.           {
  565.                load_ax(rs);
  566.                if (rt) {
  567.                     GENCODE3(op_1,0x46,rt);
  568.                     PRINTF("%s eax,[esi+%d]\n",str,(int)rt);
  569.                }
  570.           }
  571.      } else if (rt) {
  572.           load_ax(rt);
  573.      } else {
  574.           store_imm(rd,0);
  575.           return;
  576.      }
  577.      store_ax(rd);
  578. }
  579.  
  580. static void subu_r(UINT32 code)
  581. {
  582.      if (!rd) return;
  583.  
  584.      if (rs) {
  585.           if (rs==rd) {
  586.                if (rt) {
  587.                     load_ax(rt);
  588.                     GENCODE3(0x29,0x46,rd);
  589.                     PRINTF("sub [esi+%d],eax\n",(int)rd);
  590.                     //isimm[rdno] = 0;
  591.                }
  592.                return;
  593.           }
  594.           load_ax(rs);
  595.           if (rt) {
  596.                GENCODE3(0x2b,0x46,rt);
  597.                PRINTF("sub eax,[esi+%d]\n",(int)rt);
  598.           }
  599.      } else if (rt) {
  600.           load_ax(rt);
  601.           GENCODE2(0xf7,0xd8);
  602.           PRINTF("neg eax\n");
  603.      } else {
  604.           store_imm(rd,0);
  605.           return;
  606.      }
  607.      store_ax(rd);
  608. }
  609.  
  610. static void nor_r(UINT32 code)
  611. {
  612.      /* f7 d0 not eax */
  613.      if (!rd) return;
  614.  
  615.      if (rs) {
  616.           load_ax(rs);
  617.           if (rt) {
  618.                GENCODE3(0x0b,0x46,rt);
  619.                PRINTF("or eax,[esi+%d]\n",(int)rt);
  620.           }
  621.      } else if (rt) {
  622.           load_ax(rt);
  623.      } else {
  624.           store_imm(rd,-1);
  625.           return;
  626.      }
  627.      GENCODE2(0xf7,0xd0);
  628.      PRINTF("not eax\n");
  629.      store_ax(rd);
  630. }
  631.  
  632. static void and_r(UINT32 code)
  633. {
  634.      if (rd) {
  635.           if (rs && rt) {
  636.                load_ax(rs);
  637.                GENCODE3(0x23,0x46,rt);
  638.                PRINTF("and eax,[esi+%d]\n",(int)rt);
  639.                store_ax(rd);
  640.           } else {
  641.                store_imm(rd,0);
  642.           }
  643.      }
  644. }
  645.  
  646. /*
  647.      50 push   eax
  648.      ff 76 xx push  dword [esi+xx]
  649.      40 inc    eax
  650.      48 dec    eax
  651.      ff 46 xx inc   dword [esi+rs]
  652.      ff 4e xx dec   dword [esi+rs]
  653.      8d 40 xx lea   eax,[eax+imm]
  654.      31 c0 xor eax,eax
  655.      f7 d8 neg eax
  656. */
  657.  
  658. /*
  659.      9c pushf
  660.      9d popf
  661.      e9 xx xx xx xx jmp
  662.      eb xx jmp last
  663.      74 xx je  last
  664.      75 xx jne last
  665.      7c xx jl  last
  666.      7d xx jge last
  667.      7e xx jle last
  668.      7f xx jg  last
  669. */
  670.  
  671. static void cmp_i(UINT32 code,int imm)
  672. {
  673.      GENCODE3i(0x81,0x7e,rs,imm);
  674.      PRINTF("cmp [esi+%d],0%xh\n",(int)rs,imm);
  675. }
  676.  
  677. static void cmp_r(UINT32 code)
  678. {
  679.      if (!rt) { cmp_i(code,0); return; }
  680.      load_ax(rs);
  681.  
  682.      GENCODE3(0x3b,0x46,rt);
  683.      PRINTF("cmp eax,[esi+%d]\n",(int)rt);
  684. }
  685.  
  686. static void compile2(UINT32 Pc)
  687. {
  688.      FPSE_Flags |= IN_SLOT;
  689.      compile1(Pc);
  690.      FPSE_Flags &= ~IN_SLOT;
  691. }
  692.  
  693. static void push_addr(UINT32 code)
  694. {
  695.      if (rs==0) {
  696.           push_imm(immS);
  697.      } else 
  698.      if (immS) {
  699.           load_ax(rs);
  700.           add_imm(immS);
  701.           push_ax();
  702.      } else {
  703.           push_r(rs);
  704.      }
  705. }
  706.  
  707. static void call(char *str,funcptr func,int argn)
  708. {
  709. /*
  710.      b8 xx xx xx xx    mov eax,xx
  711.      ff e0             jmp eax
  712.     ff 20             jmp [eax]
  713.      ff d0             call eax
  714.     ff 10             call [eax]
  715.      ff 15 xx xx xx xx call [xx]
  716.      e8 xx xx xx xx    call xx (offset)
  717.      81 c4 xx xx xx xx add esp,2
  718.      8d 64 24 xx lea esp,[esp+2]
  719. */
  720.  
  721.      GENCODE1i(0xe8,(UINT32)func-(UINT32)(pcptr+5));
  722.      PRINTF("call %s\n",str);
  723.  
  724. /*
  725.      59 pop ecx
  726.      5a pop edx
  727. */
  728.      lastax = -1;
  729.      if (argn==4) {
  730.           GENCODE1(0x5a);
  731.           PRINTF("pop edx\n");
  732.      } else if (argn==8) {
  733.           GENCODE1(0x5a);
  734.           PRINTF("pop edx\n");
  735.           GENCODE1(0x5a);
  736.           PRINTF("pop edx\n");
  737.      } else
  738.      if (argn) {
  739. #if 0
  740.           GENCODE4(0x8d,0x64,0x24,argn);
  741.           PRINTF("lea esp,[esp+%d]\n",argn);
  742. #else
  743.           GENCODE2i(0x81,0xc4,argn);
  744.           PRINTF("add esp,%d\n",argn);
  745. #endif
  746.      }
  747. }
  748.  
  749. static void jump(void)
  750. {
  751.      call("jmppc",(funcptr)jmppc,4); /* 5 + 5 */
  752.      GENCODE2(0xff,0xe0); /* 2 */
  753.      PRINTF("jmp eax\n");
  754.      //endflg = 1;
  755. }
  756.  
  757. static void jump_imm(UINT32 newpc)
  758. {
  759.      push_imm(newpc);
  760.      jump();
  761. }
  762.  
  763. static void bxx(UINT32 code,UINT32 Pc,char *str,int op)
  764. {
  765.      UINT32 newpc;
  766.      char *base;
  767.  
  768.      if (FETCH(Pc)==0) {
  769.           /* nop */
  770.           PRINTF("%08x %08x %s\n",(int)Pc,0,"nop");
  771.      } else { 
  772.           GENCODE1(0x9c);
  773.           PRINTF("pushf\n");
  774.           compile2(Pc);
  775.           GENCODE1(0x9d);
  776.           PRINTF("popf\n");
  777.      } 
  778.  
  779.      GENCODE2(op,0);
  780.      PRINTF("%s @skip\n",str);
  781.      base = pcptr;
  782.  
  783.      newpc = Pc + immS*4;
  784. #if 0
  785.      if (COMPILED(newpc)) {
  786.           GENCODE1i(0xe9,COMPILED(newpc)-(UINT32)(pcptr+5));
  787.           PRINTF("jmp %p\n",COMPILED(newpc));
  788.      } else 
  789. #endif
  790.      {
  791.           push_imm(newpc); /* 5 */
  792.           jump(); /* 5 + 1 + 2 */
  793.      }
  794.      base[-1] = (UINT32)pcptr-(UINT32)base;
  795.      PRINTF("@skip:\n");
  796. /*
  797.           push_imm(PC+4);
  798.           jump();
  799.           endflg = 1;
  800. */
  801. }
  802.  
  803. static void store_pc(int pc)
  804. {
  805.      /* ƒfƒoƒbƒO—p  */
  806.      GENCODE2i(0xc7,0x86,rPC);
  807.      PRINTF("mov dword [esi+%d],0%xh\n",rPC,pc-4);
  808.      PRINTF(" %p %08x\n",pcptr,pc-4);
  809.      *(long*)pcptr = pc-4;
  810.      pcptr+=4;
  811. }
  812.  
  813. static void store(UINT32 code,char *str,funcptr func)
  814. {
  815.      push_r(rt);
  816.      push_addr(code);
  817.      call(str,func,8);
  818. }
  819.  
  820. static void load(UINT32 code,char *str,funcptr func)
  821. {
  822.      push_addr(code);
  823.      call(str,func,4);
  824. }
  825.  
  826. void sxx(UINT32 code,char *str,int op_r,int op_m)
  827. {
  828.      /* 8b 46 xx mov eax,[esi+xx] */
  829.      /* c1 e0 xx shl eax,xx */
  830.      /* c1 e8 xx shr eax,xx */
  831.      /* c1 f8 xx sar eax,xx */
  832.      /* c1 66 xx yy shl [esi+xx],yy */
  833.      /* c1 6e xx yy shr [esi+xx],yy */
  834.      /* c1 7e xx yy sar [esi+xx],yy */
  835.      /* 89 46 xx mov [esi+xx],eax */
  836.  
  837.      int shamt = (code>>6)&31;
  838.      if (rd && shamt) {
  839.           if (rd==rt) {
  840.                GENCODE4(0xc1,op_m,rd,shamt);
  841.                PRINTF("%s dword [esi+%d],%d\n",str,(int)rd,shamt);
  842.                //isimm[rdno] = 0;
  843.                /*if (rd==lastax)*/ lastax = -1;
  844.           } else {
  845.                load_ax(rt);
  846.                GENCODE3(0xc1,op_r,shamt);
  847.                PRINTF("%s eax,%d\n",str,shamt);
  848.                store_ax(rd);
  849.           }
  850.      }
  851. }
  852.  
  853. void sxxv(UINT32 code,char *str,int op_r,int op_m)
  854. {
  855.      /* 8b 46 xx mov eax,[esi+xx] */
  856.      /* 8b 4e xx mov ecx,[esi+xx] */
  857.      /* 8a 4e xx mov cl,[esi+xx] */
  858.      /* d3 e0    shl eax,cl */
  859.      /* d3 e8    shr eax,cl */
  860.      /* d3 f8    sar eax,cl */
  861.      /* d3 66 xx shl [esi+xx],cl */
  862.      /* d3 6e xx shr [esi+xx],cl */
  863.      /* d3 7e xx sar [esi+xx],cl */
  864.      /* 89 46 xx mov [esi+xx],eax */
  865.  
  866.      if (rd && rs) {
  867.           GENCODE3(0x8b,0x4e,rs);
  868.           PRINTF("mov ecx,[esi+%d]\n",(int)rs);
  869.           if (rd==rt) {
  870.                GENCODE3(0xd3,op_m,rd);
  871.                PRINTF("%s dword [esi+%d],cl\n",str,(int)rd);
  872.                /*if (rd==lastax)*/ lastax = -1;
  873.           } else {
  874.                load_ax(rt);
  875.                GENCODE2(0xd3,op_r);
  876.                PRINTF("%s eax,cl\n",str);
  877.                store_ax(rd);
  878.           }
  879.      }
  880. }
  881.  
  882. static void cop2gen(cop2func func)
  883. {
  884.      if (!func) return;
  885.      GENCODE2i(0x8d,0x86,idxCPR2);
  886.      PRINTF("lea eax,[esi+CPR2]\n");
  887.      push_ax();
  888.      call("cop2func",(funcptr)func,4);
  889. }
  890.  
  891. int compile1(UINT32 Pc)
  892. {
  893.      UINT32 code;
  894. //   static char strbuf[256];
  895.  
  896.      if (COMPILED(Pc)) {
  897.           PRINTF("JUMP %x %x %x\n",(int)Pc,(int)pcptr,(int)COMPILED(Pc));
  898.           GENCODE1i(0xe9,COMPILED(Pc)-(UINT32)(pcptr+5));
  899.           PRINTF("jmp %p\n",(void *)COMPILED(Pc));
  900.           Pc+=4;
  901.           endflg = 1;
  902.           return Pc;
  903.      }
  904.  
  905.      if (!in_slot) COMPILED(Pc) = (long)pcptr;
  906.         if (!(FPSE_Flags & SET_ESI)) {
  907.             GENCODE1i(0xBE,(int)®);
  908.             PRINTF("mov esi,reg\n");
  909.             FPSE_Flags |= SET_ESI;
  910.         }
  911.  
  912. /*
  913.      if (Pc==breakpoint) {
  914.           call("watch",watch,0);
  915.      }
  916. */
  917.  
  918.      code = FETCH(Pc);
  919.  
  920.      DISASM(code,Pc);
  921.  
  922.      Pc+=4;
  923.      if (code)
  924.      switch(code>>26) {
  925.  
  926.      case SPECIAL:
  927.           switch(code&63) {
  928.      /* c1 e0 xx shl eax,xx */
  929.      /* c1 e8 xx shr eax,xx */
  930.      /* c1 f8 xx sar eax,xx */
  931.      /* c1 66 xx yy shl [esi+xx],yy */
  932.      /* c1 6e xx yy shr [esi+xx],yy */
  933.      /* c1 7e xx yy sar [esi+xx],yy */
  934.  
  935.           case SLL: sxx(code,"shl",0xe0,0x66); break;
  936.           case SRL: sxx(code,"shr",0xe8,0x6e); break;
  937.           case SRA: sxx(code,"sar",0xf8,0x7e); break;
  938.  
  939.      /* d3 e0    shl eax,cl */
  940.      /* d3 e8    shr eax,cl */
  941.      /* d3 f8    sar eax,cl */
  942.      /* d3 66 xx shl [esi+xx],cl */
  943.      /* d3 6e xx shr [esi+xx],cl */
  944.      /* d3 7e xx sar [esi+xx],cl */
  945.  
  946.           case SLLV:     sxxv(code,"shl",0xe0,0x66); break;
  947.           case SRLV:     sxxv(code,"shr",0xe8,0x6e); break;
  948.           case SRAV:     sxxv(code,"sar",0xf8,0x7e); break;
  949.  
  950. /*
  951.      03 46 xx add   eax,[esi+rt]
  952.      01 46 xx add   [esi+rt],eax
  953.      2b 46 xx sub   eax,[esi+rt]
  954.      29 46 xx sub   [esi+rt],eax
  955.      23 46 xx and   eax,[esi+rt]
  956.      21 46 xx and   [esi+rt],eax
  957.      0b 46 xx or    eax,[esi+rt]
  958.      09 46 xx or    [esi+rt],eax
  959.      33 46 xx xor   eax,[esi+rt]
  960.      31 46 xx xor   [esi+rt],eax
  961. */
  962.  
  963.           case ADD: alu_r(code,"add",0x03,0x01); break;
  964.           case ADDU:     alu_r(code,"add",0x03,0x01); break;
  965.           case SUBU:     subu_r(code); break;
  966.           case SUB: subu_r(code); break;
  967.           case AND: and_r(code); break;
  968.           case OR:  alu_r(code,"or" ,0x0b,0x09); break;
  969.           case XOR: alu_r(code,"xor",0x33,0x31); break;
  970.           case NOR: nor_r(code); break;
  971.  
  972.           case SLT:
  973.                if (rd==0) break;
  974.                cmp_r(code);
  975.                GENCODE3(0xf,0x9c,0xc0);
  976.                PRINTF("setl al\n");
  977.                GENCODE1i(0x25,1);
  978.                PRINTF("and eax,1\n");
  979.                store_ax(rd);
  980.                break;
  981.           case SLTU:
  982.                if (rd==0) break;
  983.                cmp_r(code);
  984.                GENCODE3(0xf,0x92,0xc0);
  985.                PRINTF("setb al\n");
  986.                GENCODE1i(0x25,1);
  987.                PRINTF("and eax,1\n");
  988.                store_ax(rd);
  989.                break;
  990.           case DIV:
  991.                load_ax(rs);
  992.                GENCODE1(0x99);
  993.                PRINTF("cdq\n");
  994.                GENCODE3(0xf7,0x7e,rt);
  995.                PRINTF("idiv dword [esi+%d]\n",(int)rt);
  996.                store2_ax(idxrLO);
  997.                store2_dx(idxrHI);
  998.                lastax = -1;
  999.                break;
  1000.           case DIVU:
  1001.                load_ax(rs);
  1002.                GENCODE2(0x31,0xd2);
  1003.                PRINTF("xor edx,edx\n");
  1004.                GENCODE3(0xf7,0x76,rt);
  1005.                PRINTF("div dword [esi+%d]\n",(int)rt);
  1006.                store2_ax(idxrLO);
  1007.                store2_dx(idxrHI);
  1008.                lastax = -1;
  1009.                break;
  1010.           case MULT:
  1011.                load_ax(rs);
  1012.                GENCODE3(0xf7,0x6e,rt);
  1013.                PRINTF("imul dword [esi+%d]\n",(int)rt);
  1014.                store2_ax(idxrLO);
  1015.                store2_dx(idxrHI);
  1016.                lastax = -1;
  1017.                break;
  1018.           case MULTU:
  1019.                load_ax(rs);
  1020.                GENCODE3(0xf7,0x66,rt);
  1021.                PRINTF("mul dword [esi+%d]\n",(int)rt);
  1022.                store2_ax(idxrLO);
  1023.                store2_dx(idxrHI);
  1024.                lastax = -1;
  1025.                break;
  1026.           case MFHI: if (rd) { load2_ax(idxrHI); store_ax(rd); } break;
  1027.           case MFLO: if (rd) { load2_ax(idxrLO); store_ax(rd); } break;
  1028.           case MTHI: load_ax(rs); store2_ax(idxrHI); break;
  1029.           case MTLO: load_ax(rs); store2_ax(idxrLO); break;
  1030.  
  1031.           case JALR:
  1032.                store_imm(31*4,Pc+4);
  1033.                push_r(rs);
  1034.                compile2(Pc);
  1035.                jump();
  1036.                Pc+=4;
  1037.                break;
  1038.           case JR   :
  1039.                endflg = 1;
  1040.                push_r(rs);
  1041.                compile2(Pc);
  1042.                jump();
  1043.                Pc+=4;
  1044.                break;
  1045.           case BREAK:
  1046.                push_imm(Pc-4);
  1047.                push_imm(E_Bp*4);
  1048.                call("exception",(funcptr)exception,8);
  1049.                GENCODE2(0xff,0xe0);
  1050.                PRINTF("jmp eax\n");
  1051.                break;
  1052.           case SYSCALL:
  1053.                push_imm(Pc-4);
  1054.                push_imm(E_Sys*4);
  1055.                call("exception",(funcptr)exception,8);
  1056.                GENCODE2(0xff,0xe0);
  1057.                PRINTF("jmp eax\n");
  1058.                break;
  1059.           default:  NOT_IMPREMENT("special"); break;
  1060.           }
  1061.           break;
  1062.  
  1063.      case BCOND:
  1064.           switch(rtno){
  1065.           case BLTZAL:store_imm(31*4,Pc+4);
  1066.           case BLTZ:     cmp_i(code,0); bxx(code,Pc,"jge",0x7d); Pc+=4; break;
  1067.           case BGEZAL:store_imm(31*4,Pc+4);
  1068.           case BGEZ:     cmp_i(code,0); bxx(code,Pc,"jl",0x7c); Pc+=4; break;
  1069.           default:  NOT_IMPREMENT("bcond"); break;
  1070.           }
  1071.           break;
  1072.  
  1073.      /* BRANCH/JUMP */
  1074.      case J:
  1075.           endflg = 1;
  1076.           compile2(Pc);
  1077.           jump_imm((Pc&0xf0000000)|((code&0x03ffffff)<<2));
  1078.           Pc+=4;
  1079.           break;
  1080.      case JAL:
  1081.           store_imm(31*4,Pc+4);
  1082.           compile2(Pc);
  1083.           jump_imm((Pc&0xf0000000)|((code&0x03ffffff)<<2));
  1084.           Pc+=4;
  1085.           break;
  1086.      case BNE: cmp_r(code); bxx(code,Pc,"je",0x74); Pc+=4; break;
  1087.      case BEQ:
  1088.           if (rs==0 && rt==0) {
  1089.                compile2(Pc);
  1090.                jump_imm(Pc+immS*4);
  1091.                endflg = 1;
  1092.           } else {
  1093.                cmp_r(code); bxx(code,Pc,"jne",0x75);
  1094.           }
  1095.           Pc+=4;
  1096.           break;
  1097.      case BLEZ:     cmp_i(code,0); bxx(code,Pc,"jg",0x7f); Pc+=4; break;
  1098.      case BGTZ:     cmp_i(code,0); bxx(code,Pc,"jle",0x7e); Pc+=4; break;
  1099.  
  1100.      /* ALU */
  1101. /*
  1102.      05 ii ii ii ii add  eax,imm
  1103.      81 46 xx ii ii ii ii add dword [esi+rt],imm
  1104.      25 ii ii ii ii and  eax,imm
  1105.      81 66 xx ii ii ii ii and dword [esi+rt],imm
  1106.      0d ii ii ii ii or   eax,imm
  1107.      81 4e xx ii ii ii ii or  dword [esi+rt],imm
  1108.      35 ii ii ii ii xor  eax,imm
  1109.      81 76 xx ii ii ii ii xor dword [esi+rt],imm
  1110.      3d ii ii ii ii cmp  eax,imm
  1111.      81 7e xx ii ii ii ii cmp dword [esi+rt],imm
  1112.      b8 ii ii ii ii mov  eax,imm
  1113. */
  1114.      case ADDI:     add_i(code); break;
  1115.      case ADDIU:    add_i(code); break;
  1116.      case ANDI:     alu_i(code,"and",0x25,0x66); break;
  1117.      case ORI: alu_i(code,"or" ,0x0d,0x4e); break;
  1118.      case XORI:     alu_i(code,"xor",0x35,0x76); break;
  1119.      case LUI:
  1120.           {
  1121.           UINT32 imm = code<<16;
  1122.           if (!in_slot) {
  1123.                UINT32 code2 = FETCH(Pc);
  1124.             if (((code2>>16)&0x3ff) == ((rtno<<5)|rtno)) {
  1125.                switch(code2>>26) {
  1126.                case ORI:
  1127.                case XORI:
  1128.                     DISASM(code2,Pc);
  1129.                     Pc+=4;
  1130.                     imm |= code2&0xffff;
  1131.                     break;
  1132.                case ADDI:
  1133.                case ADDIU:
  1134.                     DISASM(code2,Pc);
  1135.                     Pc+=4;
  1136.                     imm += (INT16)code2;
  1137.                     break;
  1138.                }
  1139.             }
  1140.           }
  1141.           store_imm(rt,imm);
  1142.           }
  1143.           break;
  1144.      case SLTI:
  1145.           cmp_i(code,immS);
  1146.           GENCODE3(0xf,0x9c,0xc0);
  1147.           PRINTF("setl al\n");
  1148.           GENCODE1i(0x25,1);
  1149.           PRINTF("and eax,1\n");
  1150.           store_ax(rt);
  1151.           break;
  1152.      case SLTIU:
  1153.           cmp_i(code,immS);
  1154.           GENCODE3(0xf,0x92,0xc0);
  1155.           PRINTF("setb al\n");
  1156.           GENCODE1i(0x25,1);
  1157.           PRINTF("and eax,1\n");
  1158.           store_ax(rt);
  1159.           break;
  1160.  
  1161.      /* COP */
  1162.      case COP0:
  1163.           switch(rsno) {
  1164.           case MFC: load2_ax(idxCPR0+rd); store_ax(rt); break; /* MFC */
  1165.           case CFC: load2_ax(idxCCR0+rd); store_ax(rt); break; /* CFC */
  1166.           case MTC: load_ax(rt); store2_ax(idxCPR0+rd); break; /* MTC */
  1167.           case CTC: load_ax(rt); store2_ax(idxCCR0+rd); break; /* CTC */
  1168.           case 16:
  1169.                if ((code&31)==16) { /* RFE */
  1170.                     call("rfe",(funcptr)rfe,0);
  1171.                     break;
  1172.                }
  1173.           default: NOT_IMPREMENT("COP0");    break;
  1174.           }
  1175.           break;
  1176.      case COP2:
  1177.           switch(rsno) {
  1178.           case MFC:
  1179.                cop2gen(cop2readfuncptr(rdno));
  1180.                load2_ax(idxCPR2+rd); store_ax(rt);
  1181.                break; /* MFC */
  1182.           case CFC:
  1183.                cop2gen(cop2readfuncptr(rdno+32));
  1184.                load2_ax(idxCCR2+rd); store_ax(rt);
  1185.                break; /* CFC */
  1186.           case MTC:
  1187.                load_ax(rt); store2_ax(idxCPR2+rd);
  1188.                cop2gen(cop2writefuncptr(rdno));
  1189.                break; /* MTC */
  1190.           case CTC:
  1191.                load_ax(rt); store2_ax(idxCCR2+rd);
  1192.                cop2gen(cop2writefuncptr(rdno+32));
  1193.                break; /* CTC */
  1194.           default:
  1195.                cop2gen(cop2funcptr(code&0x1ffffff));
  1196.                break;
  1197.           }
  1198.           break;
  1199.  
  1200.      /* LOAD/STORE */
  1201. /*
  1202.      8b 46 xx mov   eax,[esi+xx]
  1203.      8b 56 xx mov   edx,[esi+xx]
  1204.      03 05 ii ii ii ii add    eax,[imm]
  1205.      8b 80 ii ii ii ii mov    eax,[eax+imm2]
  1206.      8a 80 ii ii ii ii mov    al,[eax+imm2]
  1207.      66 8b ii ii ii ii mov    ax,[eax+imm2]
  1208.      0f b6 80 ii ii ii ii movzx    eax,byte [eax+imm2]
  1209.      0f b7 80 ii ii ii ii movzx    eax,word [eax+imm2]
  1210.      0f be 80 ii ii ii ii movsx    eax,byte [eax+imm2]
  1211.      0f bf 80 ii ii ii ii movsx    eax,word [eax+imm2]
  1212.      89 80 ii ii ii ii mov    [eax+imm2],eax
  1213.      66 89 80 ii ii ii ii mov [eax+imm2],ax
  1214.      88 80 ii ii ii ii mov    [eax+imm2],al
  1215.      89 82 ii ii ii ii mov    [edx+imm2],eax
  1216.      66 89 82 ii ii ii ii mov [edx+imm2],ax
  1217.      88 82 ii ii ii ii mov    [edx+imm2],al
  1218. */
  1219.  
  1220.      case SB:
  1221.           store_pc(Pc);
  1222. #if 0
  1223.           { int base;
  1224.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1225.                load_dx(rs);
  1226.                load_ax(rt);
  1227.                GENCODE2i(0x88,0x82,base);
  1228.                PRINTF("mov [edx+0%xh],al\n",base);
  1229.                break;
  1230.           } }
  1231. #endif
  1232.           store(code,"write8",(funcptr)write8); break;
  1233.      case SH:
  1234.           store_pc(Pc);
  1235. #if 0
  1236.           { int base;
  1237.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1238.                load_dx(rs);
  1239.                load_ax(rt);
  1240.                GENCODE3i(0x66,0x89,0x82,base);
  1241.                PRINTF("mov [edx+0%xh],ax\n",base);
  1242.                break;
  1243.           } }
  1244. #endif
  1245.           store(code,"write16",(funcptr)write16); break;
  1246.      case SW:
  1247.           store_pc(Pc);
  1248. #if 0
  1249.           { int base;
  1250.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1251.                load_dx(rs);
  1252.                load_ax(rt);
  1253.                GENCODE2i(0x89,0x82,base);
  1254.                PRINTF("mov [edx+0%xh],eax\n",base);
  1255.                break;
  1256.           } }
  1257. #endif
  1258.           store(code,"write32",(funcptr)write32); break;
  1259.      case SWL: store(code,"swl",(funcptr)swl); break;
  1260.      case SWR: store(code,"swr",(funcptr)swr); break;
  1261.  
  1262.      case LB:
  1263.           store_pc(Pc);
  1264. #if 0
  1265.           { int base;
  1266.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1267.                load_ax(rs);
  1268.                GENCODE3i(0x0f,0xbe,0x80,base);
  1269.                PRINTF("movsx eax,byte [eax+0%xh]\n",base);
  1270.                store_ax(rt);
  1271.                break;
  1272.           } }
  1273. #endif
  1274.           load(code,"read8",(funcptr)read8);
  1275.           if (rt) {
  1276.                GENCODE3(0x0f,0xbe,0xc0); PRINTF("movsx eax,al\n");
  1277.                store_ax(rt);
  1278.           }
  1279.           break;
  1280.      case LBU:
  1281.           store_pc(Pc);
  1282. #if 0
  1283.           { int base;
  1284.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1285.                load_ax(rs);
  1286.                GENCODE3i(0x0f,0xb6,0x80,base);
  1287.                PRINTF("movzx eax,word [eax+0%xh]\n",base);
  1288.                store_ax(rt);
  1289.                break;
  1290.           } }
  1291. #endif
  1292.           load(code,"read8",(funcptr)read8);
  1293.           store_ax(rt);
  1294.           break;
  1295.      case LH:
  1296.           store_pc(Pc);
  1297. #if 0
  1298.           { int base;
  1299.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1300.                load_ax(rs);
  1301.                GENCODE3i(0x0f,0xbf,0x80,base);
  1302.                PRINTF("movsx eax,word [eax+0%xh]\n",base);
  1303.                store_ax(rt);
  1304.                break;
  1305.           } }
  1306. #endif
  1307.           load(code,"read16",(funcptr)read16);
  1308.           if (rt) {
  1309.                GENCODE3(0x0f,0xbf,0xc0); PRINTF("movsx eax,ax\n");
  1310.                store_ax(rt);
  1311.           }
  1312.           break;
  1313.      case LHU:
  1314.           store_pc(Pc);
  1315. #if 0
  1316.           { int base;
  1317.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1318.                load_ax(rs);
  1319.                GENCODE3i(0x0f,0xb7,0x80,base);
  1320.                PRINTF("movzx eax,word [eax+0%xh]\n",base);
  1321.                store_ax(rt);
  1322.                break;
  1323.           } }
  1324. #endif
  1325.           load(code,"read16",(funcptr)read16);
  1326.           store_ax(rt);
  1327.           break;
  1328.  
  1329.      case LW:
  1330.           store_pc(Pc);
  1331. #if 0
  1332.           { int base;
  1333.           if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
  1334.                load_ax(rs);
  1335.                GENCODE2i(0x8b,0x80,base);
  1336.                PRINTF("mov eax,[eax+0%xh]\n",base);
  1337.                store_ax(rt);
  1338.                break;
  1339.           } }
  1340. #endif
  1341.           load(code,"read32",(funcptr)read32);
  1342.           store_ax(rt);
  1343.           break;
  1344.      case LWL:
  1345.           push_r(rt);
  1346.           push_addr(code);
  1347.           call("lwl",(funcptr)lwl,8);
  1348.           store_ax(rt);
  1349.           break;
  1350.      case LWR:
  1351.           push_r(rt);
  1352.           push_addr(code);
  1353.           call("lwr",(funcptr)lwr,8);
  1354.           store_ax(rt);
  1355.           break;
  1356.      case SWC0:
  1357.           push2_r(rt+idxCPR0);
  1358.           push_addr(code);
  1359.           call("write32",(funcptr)write32,8);
  1360.           lastax = -1;
  1361.           break;
  1362.      case LWC0:
  1363.           load(code,"read32",(funcptr)read32);
  1364.           store2_ax(rt+idxCPR0);
  1365.           break;
  1366.      case SWC2:
  1367.           cop2gen(cop2readfuncptr(rtno));
  1368.           push2_r(rt+idxCPR2);
  1369.           push_addr(code);
  1370.           call("write32",(funcptr)write32,8);
  1371.           lastax = -1;
  1372.           break;
  1373.      case LWC2:
  1374.           load(code,"read32",(funcptr)read32);
  1375.           store2_ax(rt+idxCPR2);
  1376.           cop2gen(cop2writefuncptr(rtno));
  1377.           break;
  1378.      default:  NOT_IMPREMENT("??"); break;
  1379.      }
  1380.      return Pc;
  1381. }
  1382.  
  1383. #if 0
  1384. int compiled(UINT32 Pc)
  1385. {
  1386.      return COMPILED(Pc);
  1387. }
  1388.  
  1389. void compile(UINT32 Pc)
  1390. {
  1391.      if (COMPILED(Pc)) return;
  1392.      pcbase = baseaddr(Pc);
  1393.      endflg = 0;
  1394.      memset(isimm,0,sizeof(isimm));
  1395.      while(!endflg) {
  1396.           Pc = compile1(Pc);
  1397.      }
  1398. }
  1399.  
  1400. #endif